#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <cstring>
#include <vector>
// using namespace std;
//while :; do ps -aL | head -l && ps -aL | grep test_thread; sleep 1;done
// const int num=10;
// void* routine(void* args)
// {
//     //如果放在此处，就会导致一直输出“new线程的名字是：thread - 9”
//     //原因：id是一个局部变量，存储在栈上，每次循环时，可能线程还未来得及读取内容就被覆盖
//     //此函数的参数args每次接受的都是id的一份拷贝，所以都是同样的内容，多个线程看到的资源都是一样的
//     //就会导致这种情况
//     //等到线程最后开始运行时，读取的是最后一次写入的内容所以打印的内容都是一样的
//     //解决方法，使用new，在栈上开辟,或者使用偏移量记录上一个线程写入的最后一个位置，下个线程写入时从偏移量的位置写入
//     sleep(1);
//     std::string name = static_cast<const char*>(args);
//     delete [](char*)args;
//     int cnt = 5;
//     while(cnt--)
//     {
//         sleep(1);
//         std::cout << "new线程的名字是：" << name <<std::endl;
//     }
//     return nullptr;
// }
// int main()
// {
//     std::vector<pthread_t> tids;

//     for(int i = 0; i < num; i++)
//     {
//         pthread_t tid;
//         char *id=new char[64];
//         snprintf(id, 64, "thread - %d", i);
//         int n = pthread_create(&tid, nullptr, routine, (void* )id);
//         // sleep(1);
//         if(n != 0)
//             continue;
//         else
//             tids.push_back(tid);
//     }
//     //等待所有进程
//     for(int i = 0; i < num; i++)
//     {
//         int n = pthread_join(tids[i], nullptr);
//         if(n == 0)
//             std::cout << "等待成功" << std::endl;
//     }

// }


#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <vector>

const int num = 10;
const int buffer_size = 1024; // 足够大的共享数组
char shared_buffer[buffer_size]; // 共享数组
int offset = 0; // 偏移量

void* routine(void* args)
{
    // 获取线程参数的起始地址
    sleep(1);
    char* name = static_cast<char*>(args);
    int cnt = 5;
    while (cnt--) {
        sleep(1);
        std::cout << "new线程的名字是：" << name << std::endl;
    }
    return nullptr;
}

int main()
{
    std::vector<pthread_t> tids;

    for (int i = 0; i < num; i++) {
        pthread_t tid;

        // 计算当前线程的参数写入位置
        int current_offset = offset;
        snprintf(shared_buffer + current_offset, buffer_size - current_offset, "thread - %d", i);

        // 更新偏移量（包括字符串长度和终止符 '\0'）
        offset += strlen(shared_buffer + current_offset) + 1;

        // 创建线程，并将参数指向共享数组中的对应位置
        int n = pthread_create(&tid, nullptr, routine, (void*)(shared_buffer + current_offset));
        if (n != 0) {
            std::cerr << "线程创建失败，错误码：" << n << std::endl;
            continue;
        } else {
            tids.push_back(tid);
        }
    }

    // 等待所有线程
    for (size_t i = 0; i < tids.size(); i++) {
        int n = pthread_join(tids[i], nullptr);
        if (n == 0) {
            std::cout << "等待成功" << std::endl;
        } else {
            std::cerr << "等待失败，错误码：" << n << std::endl;
        }
    }

    return 0;
}
// class Solution {
//     public:
//         int reverseDegree(string s) {
//             int count=0;
//             for(int i=0;i<s.size();i++)
//             {
//                 count+=('z'-s[i]+1)*(i+1);
//             }
//             return count;
//         }
//     };
// int main()
// {
//     string s="abc";
//     cout<<Solution().reverseDegree(s);
//     // cout<<'z'-'a'+1<<endl;
// }


// int flag=100;
// // 线程终止的问题：
// // 1.线程的入口函数，进行return就是线程终止
// // 2.线程不能用exit终止，它是终止进程的
// // 3.使用pthread_exit终止线程

// std::string format(const pthread_t& tid)
// {
//     char id[64];
//     snprintf(id,sizeof(id),"0x%lx",tid);
//     return id;
// }

// void *run(void* arg)
// {
//     std::string name=static_cast<const char*>(arg);
//     int cnt=5;
//     pthread_t tid=pthread_self();
//     pthread_detach(tid);
//     while(cnt)
//     {
//         sleep(1);
//         std::cout<<"我是一个新线程，我的名字是:"<<name<<"  "<<format(tid)<<std::endl;
//         flag++;
//         cnt--;
//     }
//     return (void*)120;
//     // exit(13);
//     // pthread_exit((void*)30);
// }

// void showtid(pthread_t& tid)
// {
//     // std::cout<<"tid:"<<tid<<std::endl;
//     printf("tid:0x%lx\n",tid);
// }
// // 让新线程自动释放，主线程不关心新线程
// // 设置线程为分离状态
// // 技术层面：线程创建是默认需要等待的，joinable，如果不想让主线程等待
// // 等待新线程，想让新线程结束之后，自己退出，设置为分离状态(!joined or detach)
// // 可以主线程将新线程分离，也可以新线程自己分离
// // 分离的线程，依旧在进程的地址空间内，进程的所有资源，被分离的线程，依旧可以访问，可以操作
// // 主不等待新线程

// //分离操作pthread_detach
// int main()
// {
//     pthread_t tid;
//     int pid=pthread_create(&tid,nullptr,run,(void*)"thread-1");
//     showtid(tid);
//     int cnt=7;
//     // pthread_cancel(tid);
//     // std::cout<<"新线程被取消"<<std::endl;
    
//     // pthread_detach(tid);
//     // std::cout<<"新线程被分离"<<std::endl;

//     while(cnt)
//     {
//         std::cout<<"main线程"<<format(pthread_self())<<std::endl;
//         std::cout<<"主线程"<<flag<<std::endl;
//         sleep(1);
//         cnt--;
//     }
//     void* ret=nullptr;
//     // 当等待的线程出错了，进程和线程都退出了，join异常看不到，也没有意义
//     // pthread_join没有错误处理的字段，是因为当线程出错时，进程线程会退出，进程会处理错误
//     // 会阻塞式的等待
//     // 默认线程无异常
//     int n=pthread_join(tid,&ret);
//     if(n!=0)
//     {
//         std::cout<<"等待新线程错误："<<strerror(n)<<std::endl;
//     }
//     else 
//     {
//         std::cout<<"等待新线程成功"<<std::endl;
//     }
//     std::cout<<(long long int)ret<<std::endl;
//     return 0;
// }


// int a=10;
// int main()
// {
//     //pid_t id=vfork();//父子进程共享一份地址空间，对一个修改就是对两个修改
//     pid_t id=fork();//父子进程不共享地址空间，对子进程修改不会影响父进程
//     if(id==0)
//     {
//         //子进程
//         std::cout<<"child process:"<<a<<std::endl;
//         a=12;
//         std::cout<<"child process:"<<a<<std::endl;
//         // _exit(0);//使用vfork创建进程必须使用_exit()或者exec退出
//     }
//     else if(id>0)
//     {
//         //父进程
//         wait(nullptr);
//         std::cout<<"child process:"<<a<<std::endl;
//     }
//     else 
//     {
//         std::cerr<<"error"<<std::endl;
//     }
//     return 0;
// }
// void* threadrun(void* args)
// {
//     while(true)
//     {
//         sleep(1);
//         std::cout<<"新线程..."<<std::endl;
//         int a=10;
//         a/=0;
//     }
// }
// int main()
// {
//     pthread_t ptid=0;
//     pthread_create(&ptid,nullptr,threadrun,(void*)"run");
//     while(true)
//     {
//         std::cout<<"主线程..."<<std::endl;
//         sleep(1);
//     }
//     return 0;
// }